# -*-coding=utf-8-*-

import numpy as np


class Wall():
    def __init__(self, position, normal, color, mode):
        self.position = np.array(position, 'f')
        self.normal = np.array(normal, 'f')
        self.color = np.array(color, 'f')
        self.mode = mode

    def intersect(self, ray):
        """
        求交点
        """
        # 平面法向量
        n = self.normal
        # 射线方向
        u = ray.direction
        # 射线方向与平面法向量点乘
        n_u = np.dot(n, u)
        if np.abs(n_u) < 0.0000001:
            return None
        # 射线起点
        p0 = ray.position
        # 平面上任意一点
        a = self.position
        # 计算射线前进距离
        t = (np.dot(n, a) - np.dot(n, p0)) / np.dot(n, u)
        return (t, self.normal, self.color, self.mode)


class Box():
    def __init__(self):
        self.wall = []
        self.__init_wall()

    def __init_wall(self):
        self.left_wall = Wall()
        self.buttom_wall = Wall()
        self.top_wall = Wall()
        self.right_wall = Wall()
        self.front_wall = Wall()
        length = 50
        self.left_wall.normal[:] = [1, 0, 0]
        self.left_wall.color[:] = [255, 0, 0]
        self.left_wall.position[:] = [-length, 0, 0]
        self.buttom_wall.normal[:] = [0, 1, 0]
        self.buttom_wall.color[:] = [0, 255, 255]
        self.buttom_wall.position[:] = [0, -length, 0]
        self.right_wall.normal[:] = [-1, 0, 0]
        self.right_wall.color[:] = [0, 0, 255]
        self.right_wall.position[:] = [length, 0, 0]
        self.top_wall.normal[:] = [0, -1, 0]
        self.top_wall.color[:] = [255, 0, 255]
        self.top_wall.position[:] = [0, length, 0]
        self.front_wall.normal[:] = [0, 0, 1]
        self.front_wall.color[:] = [255, 255, 255]
        self.front_wall.position[:] = [0, 0, -length]

    def intersect(self, ray):
        """
        求交点
        """
        temp_distance = -1
        color = [0, 0, 0]
        temp_mode = 'diff'
        for i, wall in enumerate([self.left_wall, self.right_wall, self.buttom_wall, self.top_wall, self.front_wall]):
            ray_distance = wall.intersect(ray)
            if ray_distance is None:
                continue
            elif ray_distance > 0.0:
                # 保存最小正距离
                if temp_distance < 0.0 or ray_distance < temp_distance:
                    temp_distance = ray_distance
                    color = wall.color
                    temp_mode = wall.mode
        return [temp_distance, color, temp_mode]
